/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.etrs.formathlon.vue.jsf.form.gest;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import net.etrs.formathlon.control.exception.ExceptionManager;
import net.etrs.formathlon.entity.formation.Formation;
import net.etrs.formathlon.entity.formation.Seance;
import net.etrs.formathlon.entity.formation.SeanceTh;
import net.etrs.formathlon.entity.formation.Session;
import net.etrs.formathlon.entity.infrastructure.Salle;
import net.etrs.formathlon.persistance.formation.FormationFacade;
import net.etrs.formathlon.persistance.formation.InscriptionFacade;
import net.etrs.formathlon.persistance.formation.SeanceFacade;
import net.etrs.formathlon.persistance.formation.SessionFacade;
import net.etrs.formathlon.persistance.infrastructure.SalleFacade;
import net.etrs.formathlon.vue.jsf.utils.CUDBean;
import org.apache.commons.beanutils.BeanComparator;

/**
 * ManageBean JSF pour les pages traitant de l'administration des sessions.
 * @author OPIF
 */
@ManagedBean
@ViewScoped
public class GestSessionBean extends CUDBean<Session, SessionFacade> {

    @EJB
    private SessionFacade sessionFacade;
    @EJB
    private InscriptionFacade inscriptionFacade;
    // Utilisée pour connaitre la liste des formations
    @EJB
    private FormationFacade formationFacade;
    private Formation formation;
    // Utilisée pour connaitre la liste des salles
    @EJB
    private SalleFacade salleFacade;
    // Utilisée pour créer de nouvelles séances
    @EJB
    private SeanceFacade seanceFacade;

    @Override
    @PostConstruct
    protected void init() {
        super.init();
        formation = formationFacade.newInstance();
    }

    /**
     * Avant de créer la session récupération de la formation.
     * @param formation 
     */
    public void ajouter(Formation formation) {
        this.formation = formation;
        creer();
        initSession(formation);
    }

    @Override
    public void modifier(Session session) {
        super.modifier(session);

        Collections.sort(session.getListSeance(), new BeanComparator("dateHeureDebut"));
        this.formation = session.getFormation();
    }

    @Override //override complet
    public boolean validerCreer() {
        try {
            sessionFacade.create(getEntite());
            formationFacade.addSession(formation, getSession());
            formationFacade.update(formation);
            init();
            displayMessage("Création réussie.");
            return true;
        } catch (Exception ex) {
            displayErreur(ExceptionManager.traiter(ex));
            return false;
        }
    }

    @Override //affinage
    public boolean validerModifier() {
        sessionFacade.operationSurDate(getEntite());
        return super.validerModifier();
    }

    @Override
    public boolean validerSuppression() {
        //si pas d'inscrit
        if (getEntite().getListInscription().isEmpty() || inscriptionFacade.getNbInscrit(getEntite()) == 0) {
            formationFacade.removeSession(getSession().getFormation(), getSession());
            return super.validerSuppression();
        }
        displayAlert("On ne peut pas supprimer cette session.");
        return false;
    }

    @Override
    public void annuler() {
        init();
    }

    /**
     * Dit si la session est ouverte ou pas.
     * @param session
     * @return Vrai si la session est ouverte
     */
    public boolean isOuverte(Session session) {
        return sessionFacade.isOuverte(session);
    }

    /**
     * Dit si la session est à l'état de création donc modifiable ou pas.
     * @param session
     * @return Vrai si la session est modifiable
     */
    public boolean isModifiable(Session session) {
        return sessionFacade.isModifiable(session);
    }

    /**
     * Dit si la session est supprimable ou pas.
     * @param session
     * @return Vrai si la session est supprimable
     */
    public boolean isSupprimable(Session session) {
        return sessionFacade.isSupprimable(session);
    }

    /**
     * Action d'ouvrir la session à l'inscription.
     * @param session
     */
    public void ouvrir(Session session) {
        sessionFacade.ouvrir(session);
    }

    /**
     * Action de clôturer la session à l'inscription.
     * @param session
     */
    public void cloturer(Session session) {
        sessionFacade.cloturer(session);
    }

    /**
     * @param formation
     * @return la liste des sessions en cours d'une formation.
     */
    public List<Session> listSessionEnCours(Formation formation) {
        return sessionFacade.getListSessionEnCours(formation);
    }

    /**
     * @return the session
     */
    public Session getSession() {
        return getEntite();
    }

    /**
     * @return the formation
     */
    public Formation getFormation() {
        return formation;
    }

    /**
     * @return the salleFacade
     */
    public List<Salle> getListSalle() {
        return salleFacade.readAll();
    }

    /**
     * Lorsque l'on choisi la salle on l'affecte à la session.
     * @param salle 
     */
    public void choisirSalle(Salle salle) {
        getSession().setSalle(salle);
    }

    /**
     * Initialisation des listes de séances de la session
     * en fonction des séances théorique de la formation.
     * @param session
     * @param formation 
     */
    private void initSession(Formation formation) {
        getSession().setFormation(formation);
        List<Seance> listSeance = new ArrayList<Seance>();
        Seance seance;
        for (SeanceTh seanceTh : formation.getListSeanceTh()) {
            for (int i = 0; i < seanceTh.getNombre(); i++) {
                seance = seanceFacade.newInstance();
                seance.setSession(getSession());
                seance.setDuree(seanceTh.getDuree());
                listSeance.add(seance);
            }
        }
        getSession().setListSeance(listSeance);
    }

    /**
     * @return the formationFacade
     */
    public FormationFacade getFormationFacade() {
        return formationFacade;
    }

    @Override
    protected SessionFacade getFacade() {
        return sessionFacade;
    }

    /**
     * 
     * @param session
     * @return le nombre d'inscrit
     */
    public int nbInscrit(Session session) {
        return inscriptionFacade.getNbInscrit(session);
    }
}
